<!--
 @description
 @fileName Voice.vue
 @author zengqiongying
 @created 2022/11/03 17:57:38
-->
<template>
  <div class="voice-pop">
    <div class="voice-operat-area">
      <template v-if="showRecorder">
        <div class="voice-luyin">
          <div class="ly-txt">点击波纹结束录音</div>
          <div class="water" @click="handleStopLy">
            <CanvasWave />
          </div>
          <div class="luyin-bt">
            录制中<span class="time">{{ vioceLength }}</span>
          </div>
        </div>
      </template>
      <template v-else>
        <div class="btn-voice" @click="handleCreateVoice">
          <img src="@/assets/video/ic_voice.png">
        </div>
        <div v-if="hasVoice" class="voice-circle">
          <van-circle
            v-model="curRate"
            :rate="100"
            :stroke-width="60"
            size="64px"
            color="#16BC83"
            layer-color="rgba(22, 188, 131, 0.29)"
          >
            <div class="btn-pause-play" @click="handleClickPlay">
              <img v-if="play" src="@/assets/video/ic_pause.png">
              <img v-else src="@/assets/video/ic_replay.png">
            </div>
          </van-circle>
        </div>
      </template>
    </div>
    <div v-if="hasVoice && !showRecorder" class="btn-foot">
      <Player
        ref="player"
        class="voice-visiable"
        :src="src"
        @ready="handlePlayerReady"
        @end="handlePlayerEnd"
        @error="handlePlayerError"
        @duration="handlePlayerDuration"
        @update-time="handlePlayerUpdateTime"
      />
      <van-button type="primary" class="btn-primary" block round @click="clickConfirm">
        {{ curRate===100 ? '提交' : '继续' }}
      </van-button>
    </div>
  </div>
</template>

<script>
import Player from './Player'
import CanvasWave from './Cavans/index'
// import CanvasWave from './Cavans/Wave'
// import DemoFile from './horse.mp3'
export default {
  name: 'VoiceCreatPlay',
  components: {
    Player, CanvasWave
  },
  props: {
    value: {
      type: String,
      default: ''
    }
  },
  data() {
    return {
      showRecorder: false, // 是否开始录音
      src: '',
      curRate: 100,
      canPlay: false, // 是否可播放
      play: false, // 播放状态，true为正在播放
      totalLength: 0, // 音频总时长
      curLength: 0, // 当前播放时长
      startTime: '', // 开始录音的时间
      endTime: null, // 录音结束时间
      timer: null
    }
  },

  computed: {
    hasVoice() {
      return this.src && this.src.length
    },
    vioceLength() {
      let val = '00:00'
      if (this.startTime && this.endTime) {
        var d1 = new Date(this.startTime)
        var d2 = new Date(this.endTime)
        const t = parseInt(d2 - d1) / 1000// 两个时间相差的秒数
        const s = parseInt(t % 60) // 秒
        const m = parseInt(t / 60) // 分
        val = `${m > 10 ? m : '0' + m} : ${s > 10 ? s : '0' + s}`
      }
      return val
    }
  },
  watch: {
    value: {
      handler(v) {
        // TODO:点击录音提交前不初始化当前录音地址
        // this.src = v || ''
      },
      immediate: true
    }
  },

  created() {},

  mounted() {

  },
  beforeDestroy() {
    this.clearTimer()
  },

  methods: {
    // 开始录音
    handleCreateVoice() {
      // 调用录音功能 startRecorder
      this.$nativeHandler('startRecorder', '')
      this.startTime = new Date()
      this.endTime = null
      this.timer = setInterval(() => {
        this.endTime = new Date()
      }, 1000)
      this.$nextTick(() => {
        this.showRecorder = true
      })
    },
    handleStopLy() {
      this.showRecorder = false
      this.clearTimer()

      // Demo测试音频文件转换为base64进行测试
      /* this.convertPathToBase64Codes(DemoFile).then(base64Code => {
        this.setAdioSrc(base64Code)
      })
      return */
      // 结束录音并返回录音结果
      this.$nativeHandler('stopAndReturnRecordData', '').then(res => {
        const { data, type } = res
        console.log('录音格式', type)
        console.log('录音地址', data)
        if (data) {
          this.setAdioSrc('data:audio/mp3;base64,' + data)
          // this.setAdioSrc('data:audio/wav;base64,' + data)
        } else {
          this.$toast('录音保存失败')
        }
      })
    },
    // 文件url地址转换为base64编码
    convertPathToBase64Codes(path) {
      return new Promise((resolve, reject) => {
        const xhr = new XMLHttpRequest()
        xhr.open('GET', path, true)
        xhr.responseType = 'blob'
        xhr.onload = function() {
          if (this.status === 200) {
            const fileReader = new FileReader()
            fileReader.onload = function(e) {
              // base64编码
              resolve(e.target.result)
            }
            fileReader.onerror = reject
            fileReader.readAsDataURL(this.response)
          }
        }
        xhr.onerror = reject
        xhr.send()
      })
    },
    clearTimer() {
      if (this.timer) {
        clearInterval(this.timer)
        this.timer = null
      }
      this.startTime = null
      this.endTime = null
    },
    setAdioSrc(v) {
      this.src = v
      this.$nextTick(() => {
        if (this.hasVoice) {
          this.$refs.player && this.$refs.player.initAudio()
        }
      })
    },
    clickConfirm() {
      if (!this.hasVoice) {
        this.$toast('请点击录音')
        return
      }
      if (this.hasVoice && this.curRate === 100) {
        this.$emit('confirm', this.src)
      } else {
        // 继续播放
        this.play = true
        this.$refs.player.audioPlay(this.play)
      }
    },
    handleClickPlay() {
      if (!this.canPlay || this.totalLength === 0) {
        this.$toast('音频文件加载异常，无法播放')
        return
      }
      this.play = !this.play
      this.$refs.player.audioPlay(this.play)
    },
    handlePlayerError() {
      this.$toast('音频文件加载出错')
    },
    handlePlayerReady() {
      this.canPlay = true
    },
    handlePlayerEnd() {
      this.play = false
    },
    handlePlayerDuration(d) {
      this.totalLength = d
    },
    handlePlayerUpdateTime(d) {
      this.curLength = d.time
      if (this.totalLength === 0 || d.time === 0) {
        this.curRate = 100
        return
      }
      const r = this.curLength / this.totalLength
      this.curRate = Math.floor(r * 100)
    }
  }
}

</script>
<style lang='less' scoped>

.voice-pop{
  padding: 20px 0;
  height: 230px;
  box-sizing: border-box;
  .voice-operat-area{
    margin-top: 20px;
    display: flex;
    justify-content: center;
    align-items: center;
    .btn-voice{
      width:64PX ;
      height: 64PX;
      border-radius:50%;
      margin: 0 20px;
      overflow: hidden;
      img{
        width: 64PX;
        height: 64PX;
      }
    }
    .voice-circle{
      margin: 0 20px;
      width: 64PX;
      height: 64PX;
      border-radius: 50%;
      /* /deep/ .van-circle svg{
        z-index: 9;
      } */
    }
    .btn-pause-play{
      position: relative;
      width: 100%;
      height: 100%;
      display: flex;
      align-items: center;
      justify-content: center;
      position: relative;
      border-radius: 50%;
      img{
        width: 32PX;
        height: 32PX;
      }
    }
  }
}
.btn-foot{
  .btn-primary{
    height: 48px;
    border-radius: 12px;
    font-size: 16px;
    font-weight: bold;
    text-align: center;
    border: 0;
    background: linear-gradient(270deg, #009E77 0%, #20CE92 100%);
    color: #fff;
    letter-spacing: 1px;
  }
}
.voice-visiable{
  height:50px;
  visibility: hidden;
}
.voice-luyin{
  width: 100%;
  font-size: 12px;
  text-align: center;
  color: #B5B7C4;
  .luyin-bt{
    font-size: 16px;
    color: #B5B7C4;
    .time{
      color: #16BC83;
      font-weight: bold;
      margin-left: 10px;
    }
  }

  .water{
    position: relative;
    width: 100%;
    height: 64PX;
    margin: 14PX 0;
    overflow: hidden;
    .svg-box{
      position: absolute;
      left: 50%;
      height: 64PX;
      animation: move 1.25s linear infinite;
      &::before{
          position: absolute;
          bottom: 0;
          width: 400vmin;
          height: 64PX;
          margin-left: -200vmin;
          // background-image: linear-gradient(to right, #555 70%, transparent 0%);
          // background-image: url(./waterline.svg);
          background-image: url(~@/assets/img/water-line.jpg);
          background-position: bottom;
          background-size: 345PX 64PX;
          background-repeat: repeat-x;
          content: '';
      }
    }
  }
}
@keyframes move {
    to {
        transform: translateX(-20vmin);
    }
}
</style>
